import { REGEX } from './constants'

/**
 * 表单验证规则和函数
 */

/**
 * 必填验证
 * @param {string} message - 错误消息
 * @returns {Object}
 */
export const required = (message = '此字段为必填项') => {
  return {
    required: true,
    message,
    trigger: 'blur'
  }
}

/**
 * 长度验证
 * @param {number} min - 最小长度
 * @param {number} max - 最大长度
 * @param {string} message - 错误消息
 * @returns {Object}
 */
export const length = (min, max, message) => {
  if (!message) {
    if (min && max) {
      message = `长度应在 ${min} 到 ${max} 个字符之间`
    } else if (min) {
      message = `长度不能少于 ${min} 个字符`
    } else if (max) {
      message = `长度不能超过 ${max} 个字符`
    }
  }

  return {
    min,
    max,
    message,
    trigger: 'blur'
  }
}

/**
 * 最小长度验证
 * @param {number} min - 最小长度
 * @param {string} message - 错误消息
 * @returns {Object}
 */
export const minLength = (min, message) => {
  return length(min, undefined, message)
}

/**
 * 最大长度验证
 * @param {number} max - 最大长度
 * @param {string} message - 错误消息
 * @returns {Object}
 */
export const maxLength = (max, message) => {
  return length(undefined, max, message)
}

/**
 * 数值范围验证
 * @param {number} min - 最小值
 * @param {number} max - 最大值
 * @param {string} message - 错误消息
 * @returns {Object}
 */
export const range = (min, max, message) => {
  if (!message) {
    if (min !== undefined && max !== undefined) {
      message = `数值应在 ${min} 到 ${max} 之间`
    } else if (min !== undefined) {
      message = `数值不能小于 ${min}`
    } else if (max !== undefined) {
      message = `数值不能大于 ${max}`
    }
  }

  return {
    type: 'number',
    min,
    max,
    message,
    trigger: 'blur'
  }
}

/**
 * 最小值验证
 * @param {number} min - 最小值
 * @param {string} message - 错误消息
 * @returns {Object}
 */
export const minValue = (min, message) => {
  return range(min, undefined, message)
}

/**
 * 最大值验证
 * @param {number} max - 最大值
 * @param {string} message - 错误消息
 * @returns {Object}
 */
export const maxValue = (max, message) => {
  return range(undefined, max, message)
}

/**
 * 正则表达式验证
 * @param {RegExp} pattern - 正则表达式
 * @param {string} message - 错误消息
 * @returns {Object}
 */
export const pattern = (pattern, message = '格式不正确') => {
  return {
    pattern,
    message,
    trigger: 'blur'
  }
}

/**
 * 自定义验证函数
 * @param {Function} validator - 验证函数
 * @param {string} trigger - 触发方式
 * @returns {Object}
 */
export const custom = (validator, trigger = 'blur') => {
  return {
    validator,
    trigger
  }
}

/**
 * IP地址验证
 * @param {string} message - 错误消息
 * @returns {Object}
 */
export const ip = (message = '请输入有效的IP地址') => {
  return pattern(REGEX.IP, message)
}

/**
 * 端口号验证
 * @param {string} message - 错误消息
 * @returns {Object}
 */
export const port = (message = '请输入有效的端口号(1-65535)') => {
  return custom((rule, value, callback) => {
    if (!value) {
      callback()
      return
    }

    const portNum = parseInt(value)
    if (isNaN(portNum) || portNum < 1 || portNum > 65535) {
      callback(new Error(message))
    } else {
      callback()
    }
  })
}

/**
 * 邮箱验证
 * @param {string} message - 错误消息
 * @returns {Object}
 */
export const email = (message = '请输入有效的邮箱地址') => {
  return pattern(REGEX.EMAIL, message)
}

/**
 * URL验证
 * @param {string} message - 错误消息
 * @returns {Object}
 */
export const url = (message = '请输入有效的URL地址') => {
  return pattern(REGEX.URL, message)
}

/**
 * MAC地址验证
 * @param {string} message - 错误消息
 * @returns {Object}
 */
export const mac = (message = '请输入有效的MAC地址') => {
  return pattern(REGEX.MAC, message)
}

/**
 * 用户名验证
 * @param {string} message - 错误消息
 * @returns {Object}
 */
export const username = (message = '用户名只能包含字母、数字、下划线，长度3-20位') => {
  return pattern(/^[a-zA-Z0-9_]{3,20}$/, message)
}

/**
 * 密码验证
 * @param {number} minLen - 最小长度
 * @param {string} message - 错误消息
 * @returns {Object}
 */
export const password = (minLen = 6, message) => {
  if (!message) {
    message = `密码长度不能少于${minLen}位`
  }

  return custom((rule, value, callback) => {
    if (!value) {
      callback()
      return
    }

    if (value.length < minLen) {
      callback(new Error(message))
    } else {
      callback()
    }
  })
}

/**
 * 强密码验证
 * @param {string} message - 错误消息
 * @returns {Object}
 */
export const strongPassword = (message = '密码必须包含大小写字母、数字和特殊字符，长度8-20位') => {
  return pattern(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,20}$/, message)
}

/**
 * 确认密码验证
 * @param {string} passwordField - 密码字段名
 * @param {string} message - 错误消息
 * @returns {Object}
 */
export const confirmPassword = (passwordField = 'password', message = '两次输入的密码不一致') => {
  return custom((rule, value, callback) => {
    if (!value) {
      callback()
      return
    }

    // 这里需要从表单实例中获取密码字段的值
    // 具体实现可能需要根据使用的表单组件进行调整
    callback()
  })
}

/**
 * 手机号验证
 * @param {string} message - 错误消息
 * @returns {Object}
 */
export const phone = (message = '请输入有效的手机号码') => {
  return pattern(/^1[3-9]\d{9}$/, message)
}

/**
 * 身份证号验证
 * @param {string} message - 错误消息
 * @returns {Object}
 */
export const idCard = (message = '请输入有效的身份证号码') => {
  return pattern(
    /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/,
    message
  )
}

/**
 * 数字验证
 * @param {string} message - 错误消息
 * @returns {Object}
 */
export const number = (message = '请输入数字') => {
  return {
    type: 'number',
    message,
    trigger: 'blur'
  }
}

/**
 * 整数验证
 * @param {string} message - 错误消息
 * @returns {Object}
 */
export const integer = (message = '请输入整数') => {
  return pattern(/^-?\d+$/, message)
}

/**
 * 正整数验证
 * @param {string} message - 错误消息
 * @returns {Object}
 */
export const positiveInteger = (message = '请输入正整数') => {
  return pattern(/^[1-9]\d*$/, message)
}

/**
 * 非负整数验证
 * @param {string} message - 错误消息
 * @returns {Object}
 */
export const nonNegativeInteger = (message = '请输入非负整数') => {
  return pattern(/^\d+$/, message)
}

/**
 * 浮点数验证
 * @param {number} decimals - 小数位数
 * @param {string} message - 错误消息
 * @returns {Object}
 */
export const decimal = (decimals = 2, message) => {
  if (!message) {
    message = `请输入有效的数字（最多${decimals}位小数）`
  }

  const regex = new RegExp(`^-?\\d+(\\.\\d{1,${decimals}})?$`)
  return pattern(regex, message)
}

/**
 * 正浮点数验证
 * @param {number} decimals - 小数位数
 * @param {string} message - 错误消息
 * @returns {Object}
 */
export const positiveDecimal = (decimals = 2, message) => {
  if (!message) {
    message = `请输入正数（最多${decimals}位小数）`
  }

  const regex = new RegExp(`^\\d+(\\.\\d{1,${decimals}})?$`)
  return pattern(regex, message)
}

/**
 * 日期验证
 * @param {string} message - 错误消息
 * @returns {Object}
 */
export const date = (message = '请选择日期') => {
  return {
    type: 'date',
    message,
    trigger: 'change'
  }
}

/**
 * 日期范围验证
 * @param {string} message - 错误消息
 * @returns {Object}
 */
export const dateRange = (message = '请选择日期范围') => {
  return {
    type: 'array',
    required: true,
    message,
    trigger: 'change'
  }
}

/**
 * 数组验证
 * @param {number} min - 最小长度
 * @param {number} max - 最大长度
 * @param {string} message - 错误消息
 * @returns {Object}
 */
export const array = (min, max, message) => {
  if (!message) {
    if (min && max) {
      message = `请选择 ${min} 到 ${max} 项`
    } else if (min) {
      message = `至少选择 ${min} 项`
    } else if (max) {
      message = `最多选择 ${max} 项`
    } else {
      message = '请至少选择一项'
    }
  }

  return {
    type: 'array',
    min,
    max,
    message,
    trigger: 'change'
  }
}

/**
 * 文件大小验证
 * @param {number} maxSize - 最大大小（MB）
 * @param {string} message - 错误消息
 * @returns {Function}
 */
export const fileSize = (maxSize, message) => {
  if (!message) {
    message = `文件大小不能超过 ${maxSize}MB`
  }

  return file => {
    const isLtMaxSize = file.size / 1024 / 1024 < maxSize
    if (!isLtMaxSize) {
      throw new Error(message)
    }
    return true
  }
}

/**
 * 文件类型验证
 * @param {string[]} types - 允许的文件类型
 * @param {string} message - 错误消息
 * @returns {Function}
 */
export const fileType = (types, message) => {
  if (!message) {
    message = `只能上传 ${types.join('、')} 格式的文件`
  }

  return file => {
    const fileType = file.name.split('.').pop().toLowerCase()
    const isValidType = types.includes(fileType)
    if (!isValidType) {
      throw new Error(message)
    }
    return true
  }
}

/**
 * 图片文件验证
 * @param {number} maxSize - 最大大小（MB）
 * @param {string} message - 错误消息
 * @returns {Function}
 */
export const imageFile = (maxSize = 2, message) => {
  const types = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp']

  return file => {
    fileType(types, '只能上传图片文件')(file)
    fileSize(maxSize, message || `图片大小不能超过 ${maxSize}MB`)(file)
    return true
  }
}

/**
 * 视频文件验证
 * @param {number} maxSize - 最大大小（MB）
 * @param {string} message - 错误消息
 * @returns {Function}
 */
export const videoFile = (maxSize = 100, message) => {
  const types = ['mp4', 'avi', 'mov', 'mkv', 'flv', 'wmv', '3gp']

  return file => {
    fileType(types, '只能上传视频文件')(file)
    fileSize(maxSize, message || `视频大小不能超过 ${maxSize}MB`)(file)
    return true
  }
}

/**
 * 文档文件验证
 * @param {number} maxSize - 最大大小（MB）
 * @param {string} message - 错误消息
 * @returns {Function}
 */
export const documentFile = (maxSize = 10, message) => {
  const types = ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt']

  return file => {
    fileType(types, '只能上传文档文件')(file)
    fileSize(maxSize, message || `文档大小不能超过 ${maxSize}MB`)(file)
    return true
  }
}

/**
 * 组合验证规则
 * @param {...Object} rules - 验证规则
 * @returns {Array}
 */
export const combine = (...rules) => {
  return rules.filter(rule => rule)
}

/**
 * 设备名称验证规则
 */
export const deviceNameRules = combine(
  required('请输入设备名称'),
  length(1, 50, '设备名称长度应在1-50个字符之间')
)

/**
 * IP地址验证规则
 */
export const ipAddressRules = combine(required('请输入IP地址'), ip())

/**
 * 端口号验证规则
 */
export const portRules = combine(required('请输入端口号'), port())

/**
 * 用户名验证规则
 */
export const usernameRules = combine(required('请输入用户名'), username())

/**
 * 密码验证规则
 */
export const passwordRules = combine(required('请输入密码'), password(6))

/**
 * 邮箱验证规则
 */
export const emailRules = combine(required('请输入邮箱地址'), email())

/**
 * URL验证规则
 */
export const urlRules = combine(required('请输入URL地址'), url())
